package org.dromara.oce.utils;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Date;

/**
 * @desc: 时间工具类
 * @author: hhl
 * @date：2024/9/6 15:52
 */
@UtilityClass
@Slf4j
public class DateTimeUtil {

    /**
     * 获取当前时间的秒级时间戳 (精确到分钟)
     *
     * @return 秒级时间戳（yyyy-MM-dd HH:mm:00）
     */
    public Long getCurrMinutesTimestampSecond() {
        String strDate = DateUtil.format(LocalDateTime.now(), "yyyy-MM-dd HH:mm:00");
        return getMinutesTimestampSecond(strDate);
    }

    /**
     * 根据传入时间获取秒级时间戳 (精确到分钟)   yyyy-MM-dd HH:mm:00
     *
     * @param strDate yyyy-MM-dd HH:mm:ss
     * @return 秒级时间戳（yyyy-MM-dd HH:mm:00）
     */
    public Long getMinutesTimestampSecond(String strDate) {
        LocalDateTime parse = LocalDateTimeUtil.parse(strDate, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:00"));
        String format = DateUtil.format(parse, "yyyy-MM-dd HH:mm:00");
        DateTime of = DateTime.of(format, "yyyy-MM-dd HH:mm:ss");
        return of.getTime() / 1000;
    }

    /**
     * 取出多余的小时、分钟、秒数（01:12:12变成00:00:00）
     *
     * @param timestamp 秒级时间戳
     * @return 整数分钟的秒级时间戳
     */
    public Long getDateTimestamp(Long timestamp) {
        return DateTimeUtil.getTimestampSecond(DateTimeUtil.getStrDate(timestamp));
    }

    /**
     * 取出多余的秒数（01:01:12变成01:01:00）
     *
     * @param timestamp 秒级时间戳
     * @return 整数分钟的秒级时间戳
     */
    public Long getMinitesTimestamp(Long timestamp) {
        return timestamp - timestamp % 60;
    }

    /**
     * 取出多余的分钟、秒数（01:12:12变成01:00:00）
     *
     * @param timestamp 秒级时间戳
     * @return 整数分钟的秒级时间戳
     */
    public Long getHoursTimestamp(Long timestamp) {
        return timestamp - timestamp % 3600;
    }

    /**
     * 获取当前时间的时间戳 (精确到小时)   yyyy-MM-dd HH:00:00
     *
     * @return 秒级时间戳（yyyy-MM-dd HH）
     */
    public long getCurrHoursTimestampSecond() {
        String format = DateUtil.format(LocalDateTime.now(), "yyyy-MM-dd HH:00:00");
        DateTime of = DateTime.of(format, "yyyy-MM-dd HH:mm:ss");
        return of.getTime() / 1000;
    }

    /**
     * 根据LocalDateTime，获取毫秒时间戳
     *
     * @param localDateTime
     * @return 毫秒时间戳
     */
    public Long getTimestampMilli(LocalDateTime localDateTime) {
        Long timestamp = localDateTime.toInstant(ZoneOffset.ofHours(8)).toEpochMilli();
        return timestamp;
    }

    /**
     * 根据LocalDateTime，获取秒时间戳
     *
     * @param localDateTime
     * @return 秒时间戳
     */
    public Long getTimestampSeconds(LocalDateTime localDateTime) {
        if(localDateTime==null){
            return null;
        }
        Long timestamp = localDateTime.toInstant(ZoneOffset.ofHours(8)).toEpochMilli() / 1000;
        return timestamp;
    }

    /**
     * 秒级时间戳  转 LocalDateTime
     *
     * @param timestampSecond 秒时间戳
     * @return LocalDateTime
     */
    public LocalDateTime parseLocalDateTimeSecond(Long timestampSecond) {
        LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochSecond(timestampSecond), ZoneOffset.ofHours(8));
        return localDateTime;
    }

    /**
     * 秒级时间戳 转 日期str
     *
     * @param timestampSecond 秒时间戳
     * @return 字符串 yyyy-MM-dd
     */
    public String getStrDate(Long timestampSecond) {
        LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochSecond(timestampSecond), ZoneOffset.ofHours(8));
        return localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
    }

    /**
     * 秒级时间戳 转 时间str
     *
     * @param timestampSecond 秒级时间戳
     * @return 字符串 yyyy-MM-dd HH:mm（精确到分钟）
     */
    public String getStrHoursDate(Long timestampSecond) {
        LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochSecond(timestampSecond), ZoneOffset.ofHours(8));
        return localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
    }

    /**
     * 秒级时间戳 转 时间str
     *
     * @param timestampSecond
     * @return 字符串 yyyy-MM-dd HH:mm:ss（精确到秒）
     */
    public String getStrSecondsDate(Long timestampSecond) {
        LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochSecond(timestampSecond), ZoneOffset.ofHours(8));
        return localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }


    /**
     * 毫秒级时间戳 转 LocalDateTime
     *
     * @param timestampMilli 毫秒时间戳
     * @return LocalDateTime
     */
    public LocalDateTime parseLocalDateTimeMilli(Long timestampMilli) {
        LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(timestampMilli), ZoneOffset.ofHours(8));
        return localDateTime;
    }

    /**
     * 获取时间戳一小时前的时间戳
     *
     * @param timestampSecond
     * @return 一小时前的时间戳
     */
    public long getLastHoursTimestamp(Long timestampSecond) {
        return timestampSecond - 1 * 60 * 60;
    }

    /**
     * 获取前一天的时间戳
     * @param timestampSecond
     * @return
     */
    public long getLastDateTimestamp(Long timestampSecond) {
        return timestampSecond - 24 * 60 * 60;
    }

    /**
     * 获取秒级时间戳 一小时前的字符串
     *
     * @param timestampSecond
     * @return 一小时前的字符串
     */
    public String getStrLastHours(long timestampSecond) {
        long lastHoursTimestamp = getLastHoursTimestamp(timestampSecond);
        return getStrHoursDate(lastHoursTimestamp);
    }

    /**
     * 获取时间戳中的 小时
     *
     * @param timestampSecond 秒级时间戳
     * @return 小时数（24小时制）
     */
    public int getHours(Long timestampSecond) {
        Date date = new Date(timestampSecond * 1000);
        int hours = DateUtil.hour(date, true);
        return hours;
    }

    /**
     * 获取时间戳中的  分钟
     *
     * @param timestampSecond 秒级时间戳
     * @return 分钟数
     */
    public int getMinute(Long timestampSecond) {
        Date date = new Date(timestampSecond * 1000);
        int minute = DateUtil.minute(date);
        return minute;
    }

    public String getHoursBlock(long hoursTimestamp) {
        LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochSecond(hoursTimestamp), ZoneOffset.ofHours(8));
        return localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:00:00"));
    }

    /**
     * 判断是否是变更天数时刻（如：23号变成24号）
     *
     * @param minuteTimestamp
     * @return
     */
    public boolean isChangeDay(Long minuteTimestamp) {
        int hours = DateTimeUtil.getHours(minuteTimestamp);
        int minute = DateTimeUtil.getMinute(minuteTimestamp);
        if (hours == 0 && minute < 5) {
            return true;
        }
        return false;
    }

    /**
     * 判断是否是变更小时（如：1点变成2点）
     *
     * @param minuteTimestamp
     * @return
     */
    public boolean isChangeHours(Long minuteTimestamp) {
        int minute = DateTimeUtil.getMinute(minuteTimestamp);
        if (minute < 5) {
            return true;
        }
        return false;
    }

    /**
     * 获取传入LocalDateTime的时间戳
     * @return yyyy-MM-dd秒级时间戳
     */
    public Long getBeginTimestampSecond() {
        long timestamp = LocalDateTime.now().toLocalDate().atStartOfDay(ZoneId.systemDefault()).toInstant().toEpochMilli() / 1000;
        return timestamp;
    }

    public Long getBeginTimestampSecond(LocalDateTime localDateTime) {
        long timestamp = localDateTime.toLocalDate().atStartOfDay(ZoneId.systemDefault()).toInstant().toEpochMilli() / 1000;
        return timestamp;
    }

    /**
     * 获取传入LocalDateTime的秒级时间戳
     *
     * @param localDateTime
     * @return timestamp 秒级时间戳
     */
    public Long getTimestampSecond(LocalDateTime localDateTime) {
        long timestamp = localDateTime.toEpochSecond(ZoneOffset.ofHours(8));
        return timestamp;
    }

    /**
     * 获取当天时间戳
     *
     * @return 当天秒级时间戳
     */
    public Long getTimestampSecond() {
        return getTimestampSecond(DateUtil.today());
    }

    /**
     * 字符串日期（yyyy-MM-dd）转 秒级时间戳
     *
     * @param strDate yyyy-MM-dd
     * @return 当天秒级时间戳
     */
    public Long getTimestampSecond(String strDate) {
        try {
            if(strDate.length()>10){
                strDate = strDate.substring(0,10);
            }
            LocalDate parse = LocalDate.parse(strDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            Long timestamps = parse.atStartOfDay(ZoneId.systemDefault()).toInstant().toEpochMilli() / 1000;
            return timestamps;
        } catch (Exception e) {
            System.out.println("时间转化异常");
            return null;
        }
    }

    /**
     * 字符串日期（yyyy-MM-dd HH:mm:ss）转 秒级时间戳
     *
     * @param strDate yyyy-MM-dd
     * @return 当天秒级时间戳
     */
    public Long getTimestampSecond2(String strDate) {
        try {
            Long timestampSeconds = DateTimeUtil.getTimestampSeconds(LocalDateTime.parse(strDate, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            return timestampSeconds;
        } catch (Exception e) {
            System.out.println("时间转化异常");
            return null;
        }
    }

    /**
     * 获取某一时刻的时间戳
     *
     * @param minuteTimestamp
     * @return
     */
    public Long getOldMinuteTimestamp(Long minuteTimestamp) {
        Long oldMinuteTimestamp = minuteTimestamp;
        String strMintuesDate = DateTimeUtil.getStrHoursDate(minuteTimestamp);
        int minute = DateTimeUtil.getMinute(minuteTimestamp);
        if (minute != 0 && minute != 15 && minute != 30 && minute != 45) {
            log.info("不是0，15，30，45分钟的数据，计算属于哪个时段");
            if (minute > 0 && minute < 15) {
                oldMinuteTimestamp = DateTimeUtil.getMinutesTimestampSecond(strMintuesDate.substring(0, 14) + "00:00");
            } else if (minute > 15 && minute < 30) {
                oldMinuteTimestamp = DateTimeUtil.getMinutesTimestampSecond(strMintuesDate.substring(0, 14) + "15:00");
            } else if (minute > 30 && minute < 45) {
                oldMinuteTimestamp = DateTimeUtil.getMinutesTimestampSecond(strMintuesDate.substring(0, 14) + "30:00");
            } else if (minute > 45 && minute < 60) {
                oldMinuteTimestamp = DateTimeUtil.getMinutesTimestampSecond(strMintuesDate.substring(0, 14) + "45:00");
            }
        } else {
            oldMinuteTimestamp = DateTimeUtil.getMinitesTimestamp(minuteTimestamp);
        }
        return oldMinuteTimestamp;
    }

}
